package main

import (
	"encoding/json"
	"fmt"
	"time"
)

func main() {
	/*test51(10, 0)
	fmt.Println("上面语句执行完成, 继续...")*/
	shallowCopyMap()
}

// 注意map的变量赋值是浅拷贝, 需要修改一个全局map尽量深度拷贝, 否则容易导致并发读写问题
func shallowCopyMap() {
	sourceMap := map[string]int{"1": 1, "2": 2}

	shallowCopyMap := sourceMap
	fmt.Println(sourceMap["1"])

	shallowCopyMap["1"] = 2
	fmt.Println(sourceMap["1"])
}

// DeepCopyMap map[string]string 类型实现深拷贝
func DeepCopyMap(oldMap map[string]string) map[string]string {
	newMap := map[string]string{}
	for k, v := range oldMap {
		newMap[k] = v
	}
	return newMap
}

func test51(num1 int, num2 int) {
	//利用 defer+recover 来捕获错误: defer后加上匿名函数的调用
	defer func() {
		//调用 recover 内置函数,可以捕获错误
		err := recover()
		//如果没有捕获错误,返回值为零值: nil
		if err != nil {
			fmt.Println("错误已经捕获")
			fmt.Println("错误是:", err)
		}
	}()
	result := num1 / num2
	fmt.Println(result)

}

// 不能同时读写一个map
func testReadAndWriteErrMap() {
	readAndWriteErrMap := make(map[string]int)

	//开一个goroutine写map
	go func() {
		for j := 0; j < 1000000; j++ {
			readAndWriteErrMap[fmt.Sprintf("%d", j)] = j
		}
	}()

	//开一个goroutine读map
	go func() {
		for j := 0; j < 1000000; j++ {
			fmt.Println(readAndWriteErrMap[fmt.Sprintf("%d", j)])
		}
	}()

	//等待, 避免主进程退出
	time.Sleep(time.Second * 20)
}

// 不能同时写一个map, 并将map序列化
func tesWriteAndMarshalErrMap() {
	marshalAndWriteErrMap := make(map[string]int)

	//开一个goroutine写map
	go func() {
		for j := 0; j < 1000000; j++ {
			marshalAndWriteErrMap[fmt.Sprintf("%d", j)] = j
		}
	}()

	//开一个goroutine序列化map
	go func() {
		for j := 0; j < 1000000; j++ {
			//将map转为json格式的字节数组
			json.Marshal(marshalAndWriteErrMap)
		}
	}()

	//等待, 避免主进程退出
	time.Sleep(time.Second * 20)
}

// 允许同时读并序列化一个map
func tesReadAndMarshalMap() {
	readAndMarshalMap := make(map[string]int)
	for j := 0; j < 1000000; j++ {
		readAndMarshalMap[fmt.Sprintf("%d", j)] = j
	}
	fmt.Println("write end...")

	//开两个goroutine序列化map
	go func() {
		//将map转为json格式的字节数组
		for j := 0; j < 1000000; j++ {
			//将map转为json格式的字节数组
			json.Marshal(readAndMarshalMap)
		}
	}()

	go func() {
		//将map转为json格式的字节数组
		for j := 0; j < 1000000; j++ {
			//将map转为json格式的字节数组
			json.Marshal(readAndMarshalMap)
		}
	}()

	//开一个goroutine读map
	go func() {
		for j := 0; j < 1000000; j++ {
			fmt.Println(readAndMarshalMap[fmt.Sprintf("%d", j)])
		}
	}()

	//等待, 避免主进程退出
	time.Sleep(time.Second * 20)
}
